home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].zip / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].adf / HackBench / hbgad.c < prev    next >
C/C++ Source or Header  |  1987-07-14  |  16KB  |  500 lines

  1. /****************************************************************
  2. /*                                *
  3. /*    HackBench - Part 4 of 4 - hbgad.c - Gadgets and Menus    *
  4. /*                                *
  5. /*    Copyright (C) 1987 by Bill Kinnersley            *
  6. /*    CS Dept, Washington State Univ, Pullman, WA 99164    *
  7. /*                                *
  8. /*    Permission granted to redistribute this program        *
  9. /*    provided the copyright notice remains intact.        *
  10. /*    May not be used as part of any commercial product.    *
  11. /*                                *
  12. /****************************************************************/
  13.  
  14. #include "hb.h"
  15.  
  16. extern int drawobj(), clearobj(), openobj(), closeobj(), compobj();
  17. extern char *rindex();
  18. extern short debug;
  19. extern struct Window *wbWin, *curWin, *errWin;
  20. extern struct MyWBObject *lastObj;
  21. extern struct List wbObjs, selObjs, utilObjs;
  22.  
  23. struct MsgPort *DOSPort, *IDCMPPort, *WBPort;
  24. long IDCMPBit, WBBit;
  25. extern void *IconBase;
  26. struct DosLibrary *DosBase;
  27. struct IntuitionBase *IntuitionBase;
  28. struct GfxBase *GfxBase;
  29. struct LayersBase *LayersBase;
  30. struct DosInfo *rnInfo;
  31.  
  32. long sendpkt();
  33. struct Remember *RememberKey=NULL;
  34. char *title = "HackBench release 1.0:                                     ";
  35. char lastErr[60];
  36. BPTR initialDir;
  37.  
  38. BYTE sbuf[61], undoBuf[61];
  39. struct StringInfo ren_si = {
  40.     sbuf, undoBuf, 0, 60, 0, 0, 1, 60, 0, 0, NULL, 0, NULL
  41. };
  42. struct Gadget ren_gad = {
  43.     NULL, 1, 1, 500, 10, GADGHCOMP, STRINGCENTER | RELVERIFY,
  44.     STRGADGET, NULL, NULL, NULL, 0, (APTR)&ren_si, GID_NAME, NULL
  45. };
  46.  
  47. struct NewWindow ren_nw = {
  48.     60, 100, 504, 11, 3, 1, NULL, ACTIVATE, &ren_gad,
  49.     NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN
  50. };
  51.  
  52. /* Used to generate menu items */
  53. struct IntuiText gen_txt = {0, 1, JAM2, 5, 0, NULL, NULL, NULL};
  54.  
  55. USHORT dm_id[] = {0xfe7f, 0xfe7f, 0xfe7f, 0xce73, 0xf24f, 0xfc3f};
  56. struct Image dm_img = {0, 0, 14, 6, 1, &dm_id[0], 1, 0, NULL};
  57. struct Gadget dm_gad = {
  58.     NULL, -15, -14, 15, 6, GADGIMAGE | GRELRIGHT | GRELBOTTOM,
  59.     GADGIMMEDIATE | RIGHTBORDER, BOOLGADGET,
  60.     (APTR)&dm_img, NULL, NULL, 0, NULL, GID_DOWNSCROLL, NULL
  61. };
  62.  
  63. USHORT up_id[] = {0xfc3f, 0xf24f, 0xce73, 0xfe7f, 0xfe7f, 0xfe7f};
  64. struct Image up_img = {0, 0, 14, 6, 1, &up_id[0], 1, 0, NULL};
  65. struct Gadget up_gad = {
  66.     &dm_gad, -15, 10, 15, 6, GADGIMAGE | GRELRIGHT,
  67.     GADGIMMEDIATE | RIGHTBORDER, BOOLGADGET,
  68.     (APTR)&up_img, NULL, NULL, 0, NULL, GID_UPSCROLL, NULL
  69. };
  70.  
  71. USHORT rm_id[] = {
  72.     0xffff, 0xf9f0, 0xfe70, 0xff90,0x0000, 0xff90, 0xfe70, 0xf9f0};
  73. struct Image rm_img = {0, 0, 12, 8, 1, &rm_id[0], 1, 0, NULL};
  74. struct Gadget rm_gad = {
  75.     &up_gad, -26, -8, 12, 8, GADGIMAGE | GRELRIGHT | GRELBOTTOM,
  76.     GADGIMMEDIATE | BOTTOMBORDER, BOOLGADGET,
  77.     (APTR)&rm_img, NULL, NULL, 0, NULL, GID_RIGHTSCROLL, NULL
  78. };
  79.  
  80. USHORT lm_id[] = {
  81.     0xffff, 0xf3f0, 0xcff0, 0x3ff0, 0x00000, 0x3ff0, 0xcff0, 0xf3f0};
  82. struct Image lm_img = {0, 0, 12, 8, 1, &lm_id[0], 1, 0, NULL};
  83. struct Gadget lm_gad = {
  84.     &rm_gad, 2, -8, 12, 8, GADGIMAGE | GRELBOTTOM,
  85.     GADGIMMEDIATE | BOTTOMBORDER,
  86.     BOOLGADGET,
  87.     (APTR)&lm_img, NULL, NULL, 0, NULL, GID_LEFTSCROLL, NULL
  88. };
  89.  
  90. struct Image knob_img1, knob_img2;
  91.  
  92. struct PropInfo hs_knob = { FREEHORIZ | AUTOKNOB, 0, 0, MAXBODY, MAXBODY};
  93. struct Gadget hs_gad = {
  94.     &lm_gad, 13, -8, -40, 9, GADGIMAGE | GRELWIDTH | GRELBOTTOM,
  95.     GADGIMMEDIATE | RELVERIFY | BOTTOMBORDER, PROPGADGET,
  96.     (APTR)&knob_img1, NULL, NULL, 0, (APTR)&hs_knob,
  97.     GID_HORIZSCROLL, NULL
  98. };
  99.  
  100. struct PropInfo vs_knob = {FREEVERT | AUTOKNOB, 0, 0, MAXBODY, MAXBODY};
  101. struct Gadget vs_gad = {
  102.     &hs_gad, -15, 16, 16,-31, GADGIMAGE | GRELHEIGHT | GRELRIGHT,
  103.     GADGIMMEDIATE | RELVERIFY | RIGHTBORDER, PROPGADGET,
  104.     (APTR)&knob_img2, NULL, NULL, 0, (APTR)&vs_knob,
  105.     GID_VERTSCROLL, NULL
  106. };
  107.  
  108. struct NewWindow nw = {
  109.     0, 0, 640, 200, 0, 1,
  110.     CLOSEWINDOW | GADGETUP | GADGETDOWN | MENUPICK | NEWSIZE |
  111.         DISKINSERTED | DISKREMOVED | MOUSEBUTTONS | REFRESHWINDOW,
  112.     SMART_REFRESH | REPORTMOUSE | BORDERLESS | ACTIVATE | BACKDROP |
  113.         WBENCHWINDOW,
  114.     NULL, NULL, "", NULL, NULL, 
  115.     0, 0, 320, 186, WBENCHSCREEN
  116. };
  117.  
  118. /* Default disk icon */
  119. USHORT disk_icon[] = {
  120.     0x0000, 0x0000, 0x3ffc, 0x3f00, 0x3ffc, 0x3fc0, 0x3ffc, 0x3ff0,
  121.     0x3ffc, 0x3ffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc,
  122.     0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc,
  123.     0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x0000, 0x0000,
  124.  
  125.     0xffff, 0xffc0, 0xc0ff, 0xfcf0, 0xc0ff, 0xfc3c, 0xc0ff, 0xfc0f,
  126.     0xc0ff, 0xfc03, 0xc0ff, 0xfc03, 0xc000, 0x0003, 0xc000, 0x0003,
  127.     0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003,
  128.     0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xffff, 0xffff 
  129. };
  130. struct Image disk_img = {0, 0, 32, 16, 2, &disk_icon[0], 3, 0, NULL};
  131.  
  132. USHORT zz_ptr[] = {
  133.     0x0000, 0x0000, 0x0008, 0x0000, 0x001c, 0x0000, 0x0026, 0x0000,
  134.     0x0013, 0x0060, 0x0009, 0x00f0, 0x0006, 0x01f8,    0x0000, 0x03fc,
  135.     0x0000, 0x07f8, 0x0000, 0x0fe0, 0x0070, 0x1ff0,    0x01f8, 0x3ff8,
  136.     0x030c, 0x7ffc, 0x03dc, 0xf3fc, 0x0bbc, 0x4bfc,    0x030c, 0x03fc,
  137.     0x51f8, 0x51f8, 0x00f0, 0x00f0, 0x2000, 0x2000,    0x2000, 0x2000,
  138.     0x0000, 0x0000, 0x0000, 0x0000
  139. };
  140.  
  141. /*USHORT zz_ptr[] = {
  142.     0x0000, 0x0000, 0x0600, 0x0600, 0x0f40, 0x0f40, 0x3fe0, 0x3fe0,
  143.     0x7fe0, 0x7fe0, 0x61f0, 0x7ff0, 0x7bf8, 0x7ff8, 0xf7f8, 0xfff8,
  144.     0x61fc, 0x7ffc, 0x7f0c, 0x7ffc, 0x3fde, 0x3ffe, 0x7fbc, 0x7ffc,
  145.     0x3f0c, 0x3ffc, 0x1ff8, 0x1ff8, 0x07f0, 0x07f0, 0x01c0, 0x01c0,
  146.     0x0700, 0x0700, 0x0fc0, 0x0fc0, 0x0680, 0x0680, 0x0000, 0x0000,
  147.     0x00c0, 0x00c0, 0x00e0, 0x00e0, 0x0040, 0x0040, 0x0000, 0x0000,
  148.     0x0000, 0x0000
  149. };
  150. */
  151. USHORT x_ptr[] = {
  152.     0x0000, 0x0000, 0x0600, 0x0000, 0x1f80, 0x0000, 0x3fc0, 0x0000,
  153.     0x6660, 0x0000, 0x6060, 0x0000, 0xf0f0, 0x0000, 0xf0f0, 0x0000,
  154.     0x6060, 0x0000, 0x6660, 0x0000, 0x3fc0, 0x0000, 0x1f80, 0x0000,
  155.     0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  156. };
  157.  
  158. /* Defaults if no Disk.info file is found */
  159. struct DrawerData defDrDat = {
  160.     {1, 13, 379, 123, -1, -1, NULL,
  161.     WBENCHWINDOW | SIZEBRIGHT | SIZEBBOTTOM | SMART_REFRESH |
  162.     WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE,
  163.     NULL, NULL, "", NULL, NULL, 90, 40, -1, -1, WBENCHSCREEN},
  164.     0, 0
  165. };
  166.  
  167. struct DiskObject defDskObj = {
  168.     0, 1, {
  169.         NULL, 575, 15, 32, 16, GADGIMAGE | GADGHBOX,
  170.         RELVERIFY | GADGIMMEDIATE, BOOLGADGET,
  171.         (APTR)&disk_img, NULL, NULL, 0, NULL, 17, NULL},
  172.     WBDISK, NULL, NULL, 575, 6, &defDrDat, NULL, 0
  173. };
  174.  
  175. short menuSet = FALSE;
  176. long menuLoc = 30L;
  177. struct Menu *lastMenu = NULL, *menuStrip = NULL;
  178. char *benchNames[] = {"ParkBench", "Open", "Close", "Duplicate",
  179.             "Rename", "Info", "Discard"};
  180. char *diskNames[] = {"Disk", "Empty Trash", "Initialize"};
  181. char *specNames[] = {"Special", "Cleanup", "Last Error", "Redraw",
  182.             "Snapshot", "Version"};
  183. char *debugNames[] = {"Debug", "Trace", "Wbobjs", "SelObjs",
  184.             "UtilObjs", "Children", "Quit"};
  185.  
  186. makeMenu() {
  187.     addMenu(benchNames, 6, BLACK_FILL);
  188.     addMenu(diskNames, 2, BLACK_FILL);
  189.     addMenu(specNames, 5, BLACK_FILL);
  190.     addMenu(debugNames, 6, BLACK_FILL | ITEMENABLED);
  191.     menuSet = TRUE;
  192.     SetMenuStrip(wbWin, menuStrip);
  193. }
  194.  
  195. addMenu (itemNames, numItems, flag)
  196. char *itemNames[]; short numItems; long flag; {
  197.     short i;
  198.     long l, height=0L, width=0L;
  199.     struct Menu *menu;
  200.     struct MenuItem *firstItem, *lastItem, *menuItem;
  201.     struct IntuiText *menuText;
  202.  
  203.     menu = (struct Menu *) AllocRemember(&RememberKey,
  204.         (long)sizeof(struct Menu), MEMF_CPC);
  205.     menu->Flags = MENUENABLED;
  206.     menu->MenuName = itemNames[0];
  207.     menu->Width = 10*strlen(itemNames[0]);
  208.     menu->LeftEdge = menuLoc;
  209.     menuLoc += (long)menu->Width + 30L;
  210.     if (lastMenu) lastMenu->NextMenu = menu;
  211.     else menuStrip = menu;
  212.     lastMenu = menu;
  213.     for (i=1; i<=numItems; i++)
  214.         width = MAX(width, strlen(itemNames[i]));
  215.     /*{l = strlen(itemNames[i+1]);if  (l>width) width = l;}*/
  216.     width = 8L*width + 8L;
  217.     lastItem = NULL;
  218.     for (i=0; i<numItems; i++) {
  219.         menuItem = (struct MenuItem *)AllocRemember(&RememberKey,
  220.             (long)sizeof(struct MenuItem), MEMF_CPC);
  221.         if (lastItem) lastItem->NextItem = menuItem;
  222.         else menu->FirstItem = menuItem;
  223.         lastItem = menuItem;
  224.         menuItem->TopEdge = 10L * i;
  225.         menuItem->Height = 8L;
  226.         menuItem->Flags = flag;
  227.         menuItem->Width = width;
  228.         menuItem->MutualExclude = (~(1L<<i));
  229.         menuText = (struct IntuiText *)AllocRemember(&RememberKey,
  230.             (long)sizeof(struct IntuiText), MEMF_CPC);
  231. /*stc*/        *menuText = gen_txt;
  232.         menuText->IText = itemNames[i+1];
  233.         menuItem->ItemFill = (APTR)menuText;
  234.         height += 10L;
  235.     }
  236.     menu->Height = height;
  237. }
  238.  
  239. openAll() {
  240.     struct Process *me;
  241.     struct Screen *sc;
  242.     struct RootNode *dlRoot;
  243.  
  244.     if (!(DosBase = (struct DosLibrary *) OpenLibrary(DOSNAME,33L)))
  245.         closeAll("Requires V1.2 DOS Library");
  246.     if (!(GfxBase = (struct GfxBase *)
  247.         OpenLibrary("graphics.library", 33L)))
  248.         closeAll("Requires V1.2 Graphics Library");
  249.     if (!(LayersBase = (struct LayersBase *)
  250.         OpenLibrary("layers.library", 33L)))
  251.         closeAll("Requires V1.2 Layers Library");
  252.     if (!(IntuitionBase = (struct IntuitionBase *)
  253.         OpenLibrary("intuition.library", 33L)))
  254.         closeAll("Requires V1.2 Intuition Library");
  255.     if (!(IconBase = OpenLibrary("icon.library", 31L)))
  256.         closeAll("I give up, where's the icon library?\n");
  257.  
  258.     /* Make sure the backdrop fills the screen */
  259.     for (sc=IntuitionBase->FirstScreen; sc; sc=sc->NextScreen)
  260.         if (sc->Flags & WBENCHSCREEN) {
  261.         nw.Height = sc->Height; nw.Width = sc->Width;
  262.         break;
  263.         }
  264.     if (!(wbWin = OpenWindow(&nw)))
  265.         closeAll("Couldn't open the backdrop window\n");
  266.     if (!(WBPort = CreatePort(NULL, NULL)))
  267.         closeAll("Couldn't create the WB port\n");
  268.  
  269.     WBBit = 1L << WBPort->mp_SigBit;
  270.     IDCMPPort = wbWin->UserPort;
  271.     IDCMPBit = 1L << wbWin->UserPort->mp_SigBit;
  272.     me = (struct Process *)FindTask(NULL);
  273.     initialDir = me->pr_CurrentDir;
  274.     DOSPort = &me->pr_MsgPort;
  275.     dlRoot = (struct RootNode *) DosBase->dl_Root;
  276.     rnInfo = (struct DosInfo *) BADDR(dlRoot->rn_Info);
  277.  
  278.     NewList(&wbObjs);
  279.     NewList(&selObjs);
  280. }
  281.  
  282. doMenu(menuNum) USHORT menuNum; {
  283.     if (menuNum==MENUNULL) return;
  284.     switch ((long)menuNum) {
  285.     case OPEN: doOpen();
  286.         OffMenu(wbWin, OPEN); OnMenu(wbWin, CLOZE);
  287.         break;
  288.     case CLOZE: doList(&selObjs, SEL, closeobj);
  289.         clearSel();
  290.         break;
  291.     case DUP: error("Not implemented"); break;
  292.     case RENAME: ren(lastObj); break;
  293.     case INFO:
  294.     case DISCARD:
  295.  
  296.     case EMPTY:
  297.     case INIT:
  298.  
  299.     case CLEANUP: error("Not implemented"); break;
  300.     case ERROR: error(lastErr); break;
  301.     case REDRAW: break;
  302.     case SNAP: error("Not implemented"); break;
  303.     case VERS: error(" (C) 1987 by Bill Kinnersley"); break;
  304.  
  305.     case TRACE: debug = ~debug; break;
  306.     case WBOBJS:  dumplist(&wbObjs, MAST); break;
  307.     case SELOBJS: dumplist(&selObjs, SEL); break;
  308.     case UTILOBJS: dumplist(&utilObjs, UTIL); break;
  309.     case CHILDREN: if (!lastObj) error("No object selected");
  310.         else if (lastObj->wo_DrawerData)
  311.         dumplist(&lastObj->wo_DrawerData->dd_Children, CHILD);
  312.         break;
  313.     case QUIT: closeAll(""); break;
  314.     }
  315. }
  316.  
  317. /* Rename an object */
  318. ren(obj) struct MyWBObject *obj; {
  319.     struct IntuiMessage *msg;
  320.     struct IntuiMessage saveMsg;
  321.     USHORT gid;
  322.     char buf1[80], *buffer;
  323.     struct Window *renWin;
  324.     ULONG saveIDCMP;
  325.     struct MsgPort *handid;
  326.     long arg[1];
  327.  
  328.     if (!obj) {error("No icon selected"); return;}
  329.     if (!(buffer = AllocMem(50L, MEMF_CPC))) /* Must be aligned */
  330.         {printf("Couldn't allocate buffer"); return;}
  331.     strcpy(sbuf, obj->wo_Name); strcpy(buf1, obj->wo_Name);
  332.     if (!(renWin = OpenWindow(&ren_nw)))
  333.         closeAll("Can't open rename window");
  334.     renWin->UserPort = IDCMPPort;
  335.     saveIDCMP = wbWin->IDCMPFlags;
  336.     ModifyIDCMP(renWin, ACTIVEWINDOW | GADGETUP);
  337.     ActivateGadget(&ren_gad, renWin, NULL);
  338.     curWin = renWin;
  339.     error("Enter the new name");
  340.     for (;;) {
  341.         WaitPort(IDCMPPort);
  342.         while (msg = GetMsg(IDCMPPort)) {
  343. /*stc*/        saveMsg = *msg;
  344.         ReplyMsg(msg);
  345.         if (saveMsg.IDCMPWindow!=renWin) {
  346.             /* If user clicks somewhere else, ignore him */
  347.             SetPointer(saveMsg.IDCMPWindow, zz_ptr,
  348.             19L, 16L, -7L, -8L);
  349.             continue;
  350.         }
  351.         gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID;
  352.         switch (saveMsg.Class) {
  353.         case GADGETUP:
  354.             if (gid!=GID_NAME) break;
  355.             if (obj->wo_Type==WBDISK) {
  356.             if (strcmp(sbuf, obj->wo_Name)==0) goto rencln;
  357.             cs2bs(buffer, sbuf);
  358.             arg[0] = ((long)buffer)>>2;
  359.             if (!(handid = DeviceProc(obj->wo_Name))) {
  360.                 printf("Couldn't get handler\n");
  361.                 goto rencln;
  362.             }
  363.             if (!sendpkt(handid, ACTION_RENAME_DISK,
  364.                 arg, 1L)) {
  365.                 error("Couldn't rename the disk");
  366.                 /* User probably cancelled a requester */
  367.                 goto rencln;
  368.             }
  369.             }
  370.             else {
  371.             if (debug) printf("I should rename <%s> to <%s>\n",
  372.                 obj->wo_Name, sbuf);
  373.             strcat(buf1, ".info"); strcat(sbuf, ".info");
  374.             if (debug) printf("and <%s> to <%s>\n", buf1, sbuf);
  375.             if (rename(buf1, sbuf)==-1)
  376.                 {error("Can't rename"); goto rencln;}
  377.             *rindex(buf1,'.') = 0; *rindex(sbuf,'.') = 0;
  378.             rename(buf1, sbuf);
  379.             /* Ignore error this time--if the real file does
  380.             not exist, at least the .info has been renamed */
  381.             }
  382.             goto renok;
  383.         case GADGETDOWN:
  384.             if (gid==GID_NAME) ClearPointer(renWin);
  385.             break;
  386.         default: SetPointer(curWin, zz_ptr,  19L, 16L, -7L, -8L);
  387.         }
  388.         }
  389.     }
  390. renok:    strcpy(obj->wo_Name, sbuf);
  391.     obj->wo_NameXOffset = (obj->wo_Gadget.Width/2) - 4*strlen(sbuf);
  392.     clearSel();
  393. rencln: renWin->UserPort = NULL;
  394.     CloseWindow(renWin);
  395.     ModifyIDCMP(wbWin, saveIDCMP);
  396.     FreeMem(buffer, 50L);
  397.     ClearPointer(curWin = wbWin);
  398. }
  399.  
  400. avail() {
  401.     if (errWin) return;
  402.     sprintf(title+25, "%ld free memory", AvailMem(MEMF_PUBLIC));
  403.     SetWindowTitles(curWin, -1L, title);
  404. }
  405.  
  406. error(s) char *s; {
  407.     strcpy(lastErr, s);
  408.     DisplayBeep(wbWin->WScreen);
  409.     SetWindowTitles(curWin, -1L, s);
  410.     OnMenu(wbWin, ERROR);
  411.     errWin = curWin;
  412. }
  413.  
  414. closeAll(s) char *s; {
  415.     struct MyWBObject *obj;
  416.     struct MyDrawerData *dd;
  417.     struct Region *reg;
  418.     printf(s);
  419.     if (debug) printf("Closing things\n");
  420.     while (obj = (struct MyWBObject *)RemHead(&wbObjs)) {
  421.         if (debug) printf("Removing %lx <%s>\n", obj, obj->wo_Name);
  422.         if (dd = obj->wo_DrawerData) {
  423.             if (dd->dd_DrawerWin) {
  424.                 if (debug) printf("   (it was open)\n");
  425.                 reg = InstallClipRegion(dd->dd_DrawerWin->
  426.                     WLayer, NULL);
  427.                 DisposeRegion(reg);
  428.                 closeWinSafely(dd->dd_DrawerWin);
  429.             }
  430.             if (dd->dd_Lock) {
  431.                 if (debug) printf("Unlocking dd_Lock %lx\n",
  432.                 dd->dd_Lock);
  433.                 UnLock(dd->dd_Lock);
  434.             }
  435.         }
  436.         if (obj->wo_Lock) {
  437.             if (debug) printf("Unlocking wo_Lock %lx\n",
  438.                 obj->wo_Lock);
  439.             UnLock(obj->wo_Lock);
  440.         }
  441.         FreeFreeList(&obj->wo_FreeList);
  442.         FreeMem(obj, (long)sizeof(struct MyWBObject));
  443.     }
  444.     if (menuSet) ClearMenuStrip(wbWin, menuStrip);
  445.     FreeRemember(&RememberKey, TRUE);
  446.     if (wbWin) CloseWindow(wbWin);
  447.     if (WBPort) DeletePort(WBPort);
  448.     if (IconBase) CloseLibrary(IconBase);
  449.     CurrentDir(initialDir);
  450.     exit(0);
  451. }
  452.  
  453. closeWinSafely(win) struct Window *win; {
  454. /* This and the next courtesy Neil Katin */
  455.     Forbid();
  456.     stripIntuiMessages(win->UserPort, win);
  457.     win->UserPort = NULL;
  458.     ModifyIDCMP(win, 0L);
  459.     win->MenuStrip = NULL;
  460.     Permit();
  461.     CloseWindow(win);
  462. }
  463.  
  464. stripIntuiMessages(mp, win) struct MsgPort *mp; struct Window *win; {
  465.     struct IntuiMessage *msg, *succ;
  466.  
  467.     msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  468.     while (succ = (struct IntuiMessage *)
  469.         msg->ExecMessage.mn_Node.ln_Succ) {
  470.         if (msg->IDCMPWindow==win) {
  471.             Remove(msg);
  472.             ReplyMsg(msg);
  473.         }
  474.         msg = succ;
  475.     }
  476. }
  477.  
  478. long sendpkt(pid, action, args, nargs)
  479. struct MsgPort *pid; long action, args[], nargs; {
  480.     struct StandardPacket *packet;
  481.     long count, *pargs, res1, error;
  482.  
  483.     if (!(packet = ALLOC(StandardPacket)))
  484.         {printf("Can't allocate packet\n"); return;}
  485.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  486.     packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
  487.     packet->sp_Pkt.dp_Port         = DOSPort;
  488.     packet->sp_Pkt.dp_Type         = action;
  489.     pargs = &(packet->sp_Pkt.dp_Arg1);
  490.     for (count=0; count<nargs; count++) pargs[count] = args[count];
  491.     PutMsg(pid, packet);
  492.     WaitPort(DOSPort);
  493.     GetMsg(DOSPort);
  494.     res1 = packet->sp_Pkt.dp_Res1;
  495.     FreeMem(packet, (long)sizeof(struct StandardPacket));
  496.     if (!res1) printf("DOS error: %ld action=%ld\n",
  497.         packet->sp_Pkt.dp_Res2, packet->sp_Pkt.dp_Type);
  498.     return res1;
  499. }
  500.